﻿using CK.Sprite.Form.Core;
using CK.Sprite.Framework;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace CK.Sprite.Form.Business
{
    public class StockDomainService : DomainService, IBusinessExec
    {
        public SpriteObjectLocalCache _spriteObjectLocalCache => LazyGetRequiredService(ref spriteObjectLocalCache);
        private SpriteObjectLocalCache spriteObjectLocalCache;

        // 参数信息{applicationCode,tenantCode,Params}
        public async Task<JObject> ExecBusinessMethod(JObject execParams, IUnitOfWork unitOfWork = null)
        {
            var applicationCode = execParams["applicationCode"].ToString();
            var tenantCode = execParams["tenantCode"].ToString();
            var checkTime = DateTime.Now;
            if (execParams["params"] != null && execParams["params"]["checkTime"] != null)
            {
                checkTime = Convert.ToDateTime(execParams["params"]["checkTime"].ToString());
            }
            if (unitOfWork == null)
            {
                var businessConfig = await TenantConfigStore.FindAsync(applicationCode, tenantCode);
                await _serviceProvider.DoDapperServiceAsync(businessConfig, async (unitOfWorkNew) =>
                {
                    var stockRepository = ConnectionFactory.GetConnectionProvider(BusinessConsts.BusinessConnProviderKey).GetRepository<IStockRepository>(unitOfWorkNew);
                    await DoExecBusinessMethod(stockRepository, checkTime, applicationCode);
                });
            }
            else
            {
                var stockRepository = ConnectionFactory.GetConnectionProvider(BusinessConsts.BusinessConnProviderKey).GetRepository<IStockRepository>(unitOfWork);
                await DoExecBusinessMethod(stockRepository, checkTime, applicationCode);
            }

            return new JObject();
        }

        private async Task DoExecBusinessMethod(IStockRepository stockRepository, DateTime checkTime, string applicationCode)
        {
            await stockRepository.RemoveStockChecksAsync(checkTime);
            var objStockMgrs = _spriteObjectLocalCache.GetAll(applicationCode).FirstOrDefault(r => r.Name == "StockMgrs");
            var objStockChecks = _spriteObjectLocalCache.GetAll(applicationCode).FirstOrDefault(r => r.Name == "StockChecks");
            var mgrFields = objStockMgrs.ObjectPropertyDtos.Where(r => r.Name.StartsWith("Col_")).Select(r => r.Name).ToList();
            var checkFields = objStockChecks.ObjectPropertyDtos.Where(r => r.Name.StartsWith("Col_")).Select(r => r.Name).ToList();

            var stockCheck = await stockRepository.GetStockChecks(mgrFields, checkTime);
            var stockCheckDayIn = await stockRepository.GetStockCheckDays(mgrFields, checkTime, "in");
            var stockCheckDayOut = await stockRepository.GetStockCheckDays(mgrFields, checkTime, "out");

            await AddStockCheck(stockRepository, checkFields, stockCheckDayIn, "01_in", checkTime);
            await AddStockCheck(stockRepository, checkFields, stockCheckDayOut, "02_out", checkTime);
            await AddStockCheck(stockRepository, checkFields, stockCheck, "03_check", checkTime);
        }

        private async Task AddStockCheck(IStockRepository stockRepository, List<string> checkFields, JObject MgrData, string stockCheckType, DateTime checkTime)
        {
            JObject addInData = new JObject();
            addInData["Id"] = Guid.NewGuid();
            addInData["StockCheckType"] = stockCheckType;
            addInData["CheckTime"] = checkTime.Date;
            foreach (var checkField in checkFields)
            {
                if (MgrData["result"][checkField.ToCamelCase()] != null)
                {
                    addInData[checkField] = MgrData["result"][checkField.ToCamelCase()];
                }
                else
                {
                    addInData[checkField] = 0;
                }
            }
            await stockRepository.AddStockChecksAsync(checkFields, addInData);
        }
    }
}
